package Server;

import java.net.ServerSocket;
import java.net.Socket;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import MetroMessenger.MessageListener;
import MetroMessenger.MessageReceiver;
import MetroMessenger.MulticastSender;
import MetroMessenger.SocketMessengerConstants;
import IO.UserGUI;

public class MetroServer extends JFrame implements MessageListener
{
	private ExecutorService serverExecutor;
	private Panel buttonPanel = new Panel();
	private JTextArea info = new JTextArea();
	private boolean flag= false;
	public ExecutorService server;
	public MetroServer()
	{
		super("Metro Server");
		info.setEditable(false);
		server = Executors.newCachedThreadPool();
		add(buttonPanel,BorderLayout.NORTH);
		add(new JScrollPane(info),BorderLayout.CENTER);
		setSize(500,400);
		setVisible(true);
	}
	
	public void startServer()
	{
		serverExecutor = Executors.newCachedThreadPool();
		try
		{
			ServerSocket serverSocket = new ServerSocket(SocketMessengerConstants.SERVER_PORT,100);
			info.append(String.format("%s%d%s\n\n","Server listening on port --->",SocketMessengerConstants.SERVER_PORT,"...."));
			while(flag)
			{
				Socket clientSocket = serverSocket.accept();
				serverExecutor.execute(new MessageReceiver(this,clientSocket));
				info.append("Connection Recieved From : " + clientSocket.getInetAddress() + " \n\n");
			}
			
		}
		catch(IOException ioException)
		{
			ioException.printStackTrace();
		}
		
		finally
		{
			info.append("\n\nServer Stopped Listening.....");
		}
	}
	public void messageReceived(String message) 
	{
		StringTokenizer inp = new StringTokenizer(message , SocketMessengerConstants.MESSAGE_SEPARATOR);
		String login = null,dis = null;
		if(inp.hasMoreTokens())
			login = inp.nextToken();
		if(inp.hasMoreTokens())
			dis = inp.nextToken();
		if(dis.equals(SocketMessengerConstants.DISCONNECT_STRING))
			info.append(login +SocketMessengerConstants.MESSAGE_SEPARATOR + "disconected\n\n");
		else
		{
			try 
			{
				message = ServerMessageProcessor.process(message);
			}
			catch (IOException e)
			{
				JOptionPane.showMessageDialog(null,e.getMessage());
			}
		    serverExecutor.execute(new MulticastSender( message.getBytes() ) );
		}
	}
	
	class Panel extends JPanel
	{
		private JButton startServer = new JButton("Start Server");
		private JButton stopServer = new JButton("Stop Server");
		private JButton modify = new JButton("Modify Database");
		private UserGUI databaseUI;
		public Panel()
		{
			setLayout(new FlowLayout());
			stopServer.setEnabled(false);
			modify.setEnabled(false);
			
			startServer.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent Event) 
				{
					if(Event.getSource()==startServer)
					{
						Thread Server = new Thread()
						{
							public void run()
							{
								flag=true;
								startServer();
							}
						};
						startServer.setEnabled(false);
						stopServer.setEnabled(true);
						modify.setEnabled(true);
						server.execute(Server);
						databaseUI = new UserGUI();
					}
				}
				
			});
			
			stopServer.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent Event) 
				{
					if(Event.getSource()==stopServer)
					{
						flag=false;
					}
					startServer.setEnabled(true);
					stopServer.setEnabled(false);
					modify.setEnabled(false);
				}
				
			});
			
			modify.addActionListener(
					new ActionListener()
					{
						public void actionPerformed(ActionEvent event) 
						{
							if(event.getSource()==modify)
							{
								databaseUI.setVisible(true);
							}
						}
						
					});
			
			add(startServer);
			add(stopServer);
			add(modify);
		}
	}
}
